Made in 2017

Gates Of Glory

. Project LinkGithub

The Game

Gates Of Glory is a castle defense game in which you have to defend against waves. These waves are endless and keep getting harder every wave. After certain waves there will be men enemies introduces these will have different stats. You can also place traps which will slow down enemies or damage them. The enemies will try to get to the throne in the middle they will first have to pass a gate. The gate can be open by the player or be broken. After the gate the enemy will have to take all the gold before breaking the throne this can create interesting end game tactics. You as player can also make rooms that can help you there is a minion room to spawn your allies a healing room to heal your allies a damage room to damage the enemies and a barrage room to do lots of damage in a specific part of that map. The Ontario will collect data so you can see how match you have made spend etc. And the generator will heal the health of your gate over time.

My Contribution

The project was made in 10 weeks by two developers and two artists. I was responsible for the AI, Wave system and the gate and throne. The enemies each have have their own speed that gets randomized slightly when they spawn to create variation. The height and pitch for the audio of the battle cry is randomized slightly. The enemies and allies use collision to detect if they are in reach of an enemy or gate. The gate can be closed and opened at will unless it's broken in that case it will stay open. Your allies will attack the enemy closest to the throne if there are no enemies or all enemies already hit their cap of how many allies they can fight at once the ally will go to the outside of the closest gate to wait for new enemies.

What would I do different?

What I would do differently: I would use inheritress properly. I would change the way the soldiers currently detect where they have to go. I would make it so based on its position it could see if it falls in the areas meet for a damageable. This also lessons the need for codependent sense the damageable data and location can be stored in a singleton. I would also make the enemies walk along 3 or more strait paths instead of using pathfinder this would make it less demanding.

Damagebles

This is from the damagebles Class This is the base class for all the damageble thing like the enemies allies but also the gates and the throne. public Stats myStats; public virtual void TakeDamage(float damage){ myStats.health.currentValue -= damage; }

Soldier

This is from the Soldier Class This class holds the bases for the movement of the AI. Movement is done using the unity navmesh. public NavMeshAgent agent; public float attackCooldown; public Transform targetTransform; public Animator anim; public bool inFight; public AudioSource myAudiosource; void Start() { MyStart(); } public virtual void MyStart() { if(agent != null) { agent.speed = Random.Range(1.75f, 2.25f); } myAudiosource.pitch = Random.Range(0.75f, 1.25f); myAudiosource.volume = Random.Range(0.01f, 0.08f); transform.localScale *= Random.Range(0.9f, 1.1f); } public override void TakeDamage(float damage) { }

Knight

This is part of the class used for the knight later we desided to at a roman like soldier this enemy uses this script aswell. void OnTriggerEnter(Collider other) { if(targetTransform != null && targetTransform == other.transform) { targetTransform.gameObject.GetComponent<Enemy>().StartBattle(this); anim.SetBool("Attack", true); anim.SetBool("Idle", false); inFight = true; agent.isStopped = true; StopAllCoroutines(); StartCoroutine(Attack()); } } void OnCollisionEnter(Collision collision) { if (collision.transform == targetTransform) { agent.isStopped = true; if(transform.position.x > 0) { transform.localEulerAngles = new Vector3(0,90,0); } else { transform.localEulerAngles = new Vector3(0, -90, 0); } anim.SetBool("Idle", true); } }

Enemy Knight

This is part of the class used for the Enemyknight. public override void TakeDamage(float damage) { myStats.health.currentValue -= damage; if(myStats.health.currentValue <= 0) { StopAllCoroutines(); ObjectPooler.instance.AddToPool("Enemy Knight", gameObject); ResourceManager.instance.AddGold(ResourceManager.instance.normalEnemyGoldReward); } } void OnCollisionEnter(Collision collision) { if(collision.transform == targetTransform) { StartBattle(target); if(targetTransform.tag == "Defense") { targetTransform.GetComponent<CastleDeffensePoint>().attackingMe.Add(this); } agent.isStopped = true; attackingCastle = true; target = collision.gameObject.GetComponent<Damagebles>(); } } void OnTriggerExit(Collider other) { if(targetTransform != null && targetTransform.gameObject.activeSelf == false) { targetTransform = null; StopBattle(); FindNewTarget(); } }

Gate

This is part of the class used for the Gate. public virtual void DirectDamage(float damage) { TakeDamage(damage); } public override void TakeDamage(float damage){ myStats.health.currentValue -= damage; if (healthbarFill != null) { healthbarFill.fillAmount = (myStats.health.currentValue / myStats.health.baseValue); } }

Throne

This is part of the class used for the Throne. public override void TakeDamage(float damage) { if(ResourceManager.instance.goldPrefabsInScene.Count > 0) { ResourceManager.instance.RemoveGold(1, false); } else { damage = Mathf.Abs(ResourceManager.instance.goldPrefabsInScene.Count - Mathf.RoundToInt(damage / 10)); ResourceManager.instance.RemoveGold(ResourceManager.instance.goldPrefabsInScene.Count, false); myStats.health.currentValue -= damage; myStats.health.currentValue -= damage; HPBar(); if(healthbarFill != null) { healthbarFill.fillAmount = (myStats.health.currentValue / myStats.health.baseValue); if(secondThroneHealthBarFill != null) { secondThroneHealthBarFill.fillAmount = (myStats.health.currentValue / myStats.health.baseValue); } } if(myStats.health.currentValue <= 0) { if(GameManager.instance.gameState == GameManager.GameState.Playing) { StartCoroutine(UIManager.instance.GameOver()); } } } }

. Project LinkGithub

s